/* * Copyright 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.tabcompat.lib; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTransaction; import android.view.View; import android.widget.TabHost; import android.widget.TabHost.TabSpec; import java.util.HashMap; /** * This is a helper class to build tabs on pre-Honeycomb. Call {@link * TabCompatActivity#getTabHelper()} to get the generic instance for * compatibility with other versions. * * It implements a generic mechanism for associating fragments with the tabs in a tab host. It * relies on a trick: Normally a tab host has a simple API for supplying a View or Intent that each * tab will show. This is not sufficient for switching between fragments. So instead we make the * content part of the tab host 0dp high (it is not shown) and this supplies its own dummy view to * show as the tab content. It listens to changes in tabs, then passes the event back to the tab's * callback interface so the activity can take care of switching to the correct fragment. */ public class TabHelperEclair extends TabHelper implements TabHost.OnTabChangeListener { private final HashMap<String, CompatTab> mTabs = new HashMap<String, CompatTab>(); private TabHost mTabHost; CompatTabListener mCallback; CompatTab mLastTab; protected TabHelperEclair(FragmentActivity activity) { super(activity); mActivity = activity; } @Override protected void setUp() { if (mTabHost == null) { mTabHost = (TabHost) mActivity.findViewById(android.R.id.tabhost); mTabHost.setup(); mTabHost.setOnTabChangedListener(this); } } @Override public void addTab(CompatTab tab) { String tag = tab.getTag(); TabSpec spec; if (tab.getIcon() != null) { spec = mTabHost.newTabSpec(tag).setIndicator(tab.getText(), tab.getIcon()); } else { spec = mTabHost.newTabSpec(tag).setIndicator(tab.getText()); } spec.setContent(new DummyTabFactory(mActivity)); // Check to see if we already have a fragment for this tab, probably // from a previously saved state. If so, deactivate it, because our // initial state is that a tab isn't shown. Fragment fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag); tab.setFragment(fragment); if (fragment != null && !fragment.isDetached()) { FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction(); ft.detach(fragment); ft.commit(); } mTabs.put(tag, tab); mTabHost.addTab(spec); } /** * Converts the basic "tab changed" event for TabWidget into the three possible events for * CompatTabListener: selected, unselected, reselected. */ @Override public void onTabChanged(String tabId) { CompatTab newTab = mTabs.get(tabId); FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction(); if (mLastTab != newTab) { if (mLastTab != null) { if (mLastTab.getFragment() != null) { // Pass the unselected event back to the tab's CompatTabListener mLastTab.getCallback().onTabUnselected(mLastTab, ft); } } if (newTab != null) { // Pass the selected event back to the tab's CompatTabListener newTab.getCallback().onTabSelected(newTab, ft); } mLastTab = newTab; } else { // Pass the re-selected event back to the tab's CompatTabListener newTab.getCallback().onTabReselected(newTab, ft); } ft.commit(); mActivity.getSupportFragmentManager().executePendingTransactions(); } @Override protected void onSaveInstanceState(Bundle outState) { // Save and restore the selected tab for rotations/restarts. outState.putString("tab", mTabHost.getCurrentTabTag()); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { if (savedInstanceState != null) { mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); } } /** * Backwards-compatibility mumbo jumbo */ static class DummyTabFactory implements TabHost.TabContentFactory { private final Context mContext; public DummyTabFactory(Context context) { mContext = context; } @Override public View createTabContent(String tag) { View v = new View(mContext); v.setMinimumWidth(0); v.setMinimumHeight(0); return v; } } }